﻿#region Header

/*
Remote views based on linq
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Reflection;

#endregion

namespace Sebarf.Utils.Interfaces {
	/// <summary>
	/// Interface for a flattener service. It takes an object and returns all attached objects (the object tree) as a list of objects.
	/// Implementations should protect from circular references and so on.
	/// The FieldInfoLookup is in/out. For performance reasons, the flattener can be initialized with a pre-existing list.
	/// 
	/// </summary>
	public interface IObjectHierarchyFlattenerService {
		/// <summary>
		/// List with field info per type. Will be created if not set externally. Can be set externally to speed up performance.
		/// </summary>
		Dictionary<Type, List<FieldInfo>> FieldInfoLookup { get; set; }

		#region Public Methods

		/// <summary>
		/// Flattens the giben object. Returns all objects attached to the given object.
		/// </summary>
		/// <param name="o"></param>
		/// <returns></returns>
		List<object> Flatten(object o);

		/// <summary>
		/// Flattens the given object and applying the collector for each object found.
		/// </summary>
		/// <param name="o"></param>
		/// <param name="collector"></param>
		/// <param name="output"></param>
		/// <returns></returns>
		object[] Flatten(object objectToFlatten, delMetadataCollector collector, ref object output);

		/// <summary>
		/// Flattens the given object but instead of returning all objects we return all objects with
		/// their parent relation.
		/// </summary>
		/// <param name="o"></param>
		/// <returns></returns>
		List<ExtendMetadata> ExtendedFlatten(object o);

		/// <summary>
		/// Return all properties of a type. This implementation should return the properties 
		/// it is using for flattening (reachability of tree is done through property hangling)
		/// </summary>
		/// <param name="t"></param>
		/// <returns></returns>
		PropertyInfo[] GetAllProperties(Type t);

		#endregion
	}

	public delegate void delMetadataCollector(object[] args, ref object output);

	/// <summary>
	/// Representing object/parent-object relation
	/// </summary>
	public class ExtendMetadata {
		public Object CurrentObject { get; set; }
		public object ParentObject { get; set; }
		public FieldInfo ParentField { get; set; }
	}
}